package com.uduemc.biso.node.module.common.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.github.pagehelper.PageInfo;
import com.uduemc.biso.core.utils.RestResult;
import com.uduemc.biso.node.core.dto.FeignFindInfoBySystemProductIds;
import com.uduemc.biso.node.core.entities.SProduct;
import com.uduemc.biso.node.core.entities.SSystem;
import com.uduemc.biso.node.core.entities.custom.Product;
import com.uduemc.biso.node.core.entities.custom.ProductDataTableForList;
import com.uduemc.biso.node.module.common.service.CProductService;

@RestController
@RequestMapping("/common/product")
public class CProductController {

	private static final Logger logger = LoggerFactory.getLogger(CProductController.class);

	@Autowired
	private CProductService cProductServiceImpl;

	/**
	 * 插入文章内容数据
	 * 
	 * @param article
	 * @param errors
	 * @return
	 */
	@PostMapping("/insert")
	public RestResult insert(@Valid @RequestBody Product product, BindingResult errors) {
		logger.info(product.toString());
		if (errors.hasErrors()) {
			Map<String, Object> message = new HashMap<>();
			for (FieldError fieldError : errors.getFieldErrors()) {
				String field = fieldError.getField();
				String defaultMessage = fieldError.getDefaultMessage();
				message.put(field, defaultMessage);
			}

			return RestResult.error(message);
		}
		Product data = cProductServiceImpl.insert(product);
		return RestResult.ok(data, Product.class.toString());
	}

	/**
	 * 修改文章内容数据
	 * 
	 * @param article
	 * @param errors
	 * @return
	 */
	@PostMapping("/update")
	public RestResult update(@Valid @RequestBody Product product, BindingResult errors) {
		logger.info(product.toString());
		if (errors.hasErrors()) {
			Map<String, Object> message = new HashMap<>();
			for (FieldError fieldError : errors.getFieldErrors()) {
				String field = fieldError.getField();
				String defaultMessage = fieldError.getDefaultMessage();
				message.put(field, defaultMessage);
			}

			return RestResult.error(message);
		}
		Product data = cProductServiceImpl.update(product);
		return RestResult.ok(data, Product.class.toString());
	}

	/**
	 * 通过 hostId、siteId、articleId 获取 Product 数据
	 * 
	 * @param hostId
	 * @param siteId
	 * @param articleId
	 * @return
	 */
	@GetMapping("/find-by-host-site-product-id/{hostId:\\d+}/{siteId:\\d+}/{productId:\\d+}")
	public RestResult findByHostSiteProductId(@PathVariable("hostId") long hostId, @PathVariable("siteId") long siteId,
			@PathVariable("productId") long productId) {
		if (productId < 1) {
			return RestResult.noData();
		}
		Product data = cProductServiceImpl.findByHostSiteProductId(hostId, siteId, productId);
		if (data == null) {
			return RestResult.noData();
		}
		return RestResult.ok(data, Product.class.toString());
	}

	/**
	 * 批量放入回收站
	 * 
	 * @param ids
	 * @return
	 */
	@PostMapping("/delete-by-list-sproduct")
	public RestResult deleteByListSProduct(@RequestBody List<SProduct> listSProduct) {
		logger.info("deleteByHostSiteIdAndProductIds listSProduct: " + listSProduct.toString());
		if (CollectionUtils.isEmpty(listSProduct)) {
			return RestResult.error();
		}
		boolean bool = cProductServiceImpl.deleteByListSProduct(listSProduct);
		return RestResult.ok(bool, Boolean.class.toString());
	}

	/**
	 * 从回收站中批量还原
	 * 
	 * @param ids
	 * @return
	 */
	@PostMapping("/reduction-by-list-sproduct")
	public RestResult reductionByListSProduct(@RequestBody List<SProduct> listSProduct) {
		logger.info("reductionByListSProduct listSProduct: " + listSProduct.toString());
		if (CollectionUtils.isEmpty(listSProduct)) {
			return RestResult.error();
		}
		boolean bool = cProductServiceImpl.reductionByListSProduct(listSProduct);
		return RestResult.ok(bool, Boolean.class.toString());
	}

	/**
	 * 回收站批量清除
	 * 
	 * @param ids
	 * @return
	 */
	@PostMapping("/clean-recycle")
	public RestResult cleanRecycle(@RequestBody List<SProduct> listSProduct) {
		logger.info("cleanRecycle listSProduct: " + listSProduct.toString());
		if (CollectionUtils.isEmpty(listSProduct)) {
			return RestResult.error();
		}
		boolean bool = cProductServiceImpl.cleanRecycle(listSProduct);
		return RestResult.ok(bool, Boolean.class.toString());
	}

	/**
	 * 回收站清空
	 * 
	 * @param sSystem
	 * @return
	 */
	@PostMapping("/clean-recycle-all")
	public RestResult cleanRecycleAll(@RequestBody SSystem sSystem) {
		logger.info("cleanRecycleAll sSystem: " + sSystem.toString());
		boolean bool = cProductServiceImpl.cleanRecycleAll(sSystem);
		return RestResult.ok(bool, Boolean.class.toString());
	}

	/**
	 * 通过 hostId、siteId、systemId、categoryId、name 获取产品列表数据，同时带有的分页以及页面大小分别为
	 * page、limit
	 * 
	 * @param hostId
	 * @param siteId
	 * @param systemId
	 * @param categoryId
	 * @param name
	 * @param page
	 * @param limit
	 * @return
	 */
	@PostMapping("/find-infos-by-host-site-system-category-id-name-and-page-limit")
	public RestResult findInfosByHostSiteSystemCategoryIdNameAndPageLimit(@RequestParam("hostId") long hostId, @RequestParam("siteId") long siteId,
			@RequestParam("systemId") long systemId, @RequestParam("categoryId") long categoryId, @RequestParam("name") String name,
			@RequestParam("page") int page, @RequestParam("limit") int limit) {
		PageInfo<ProductDataTableForList> data = cProductServiceImpl.findInfosByHostSiteSystemCategoryIdNameAndPageLimit(hostId, siteId, systemId, categoryId,
				name, page, limit);
		return RestResult.ok(data, PageInfo.class.toString());
	}

	/**
	 * 与 findInfosByHostSiteSystemCategoryIdNameAndPageLimit 上面的不同在于 通过 keyword
	 * 匹配的不仅仅是 title 还有 info 简介部分
	 * 
	 * @param hostId
	 * @param siteId
	 * @param systemId
	 * @param categoryId
	 * @param keyword
	 * @param page
	 * @param limit
	 * @return
	 */
	@PostMapping("/find-ok-infos-by-host-site-system-category-id-keyword-and-page-limit")
	public RestResult findOkInfosByHostSiteSystemCategoryIdKeywordAndPageLimit(@RequestParam("hostId") long hostId, @RequestParam("siteId") long siteId,
			@RequestParam("systemId") long systemId, @RequestParam("categoryId") long categoryId,
			@RequestParam(value = "keyword", defaultValue = "") String keyword, @RequestParam("page") int page, @RequestParam("limit") int limit) {
		PageInfo<ProductDataTableForList> data = cProductServiceImpl.findOkInfosByHostSiteSystemCategoryIdKeywordAndPageLimit(hostId, siteId, systemId,
				categoryId, keyword, page, limit);

		return RestResult.ok(data, PageInfo.class.toString());
	}

	/**
	 * 通过 hostId、siteId、systemId、productId 获取产品数据
	 * 
	 * @param hostId
	 * @param siteId
	 * @param systemId
	 * @param pid
	 * @return
	 */
	@PostMapping("/find-info-by-system-product-id")
	public RestResult findInfoBySystemProductId(@RequestParam("hostId") long hostId, @RequestParam("siteId") long siteId,
			@RequestParam("systemId") long systemId, @RequestParam("productId") long productId) {
		ProductDataTableForList data = cProductServiceImpl.findInfoBySystemProductId(hostId, siteId, systemId, productId);
		return RestResult.ok(data, ProductDataTableForList.class.toString());
	}

	/**
	 * 通过 传入对象的 hostId、siteId、systemId 以及 productIds 获取产品数据链表
	 * 
	 * @param feignFindInfoBySystemProductIds
	 * @return
	 */
	@PostMapping("/find-infos-by-system-product-ids")
	public RestResult findInfosBySystemProductIds(@RequestBody FeignFindInfoBySystemProductIds feignFindInfoBySystemProductIds) {
		List<ProductDataTableForList> data = cProductServiceImpl.findInfosBySystemProductIds(feignFindInfoBySystemProductIds.getHostId(),
				feignFindInfoBySystemProductIds.getSiteId(), feignFindInfoBySystemProductIds.getSystemId(), feignFindInfoBySystemProductIds.getProductIds());
		return RestResult.ok(data, ProductDataTableForList.class.toString(), true);
	}
}
